﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace FrameOperateSync
{
    /// <summary>
    /// 帧驱动
    /// </summary>
    public partial class FrameTicker
    {
        public event Action<int,int> EventTicker
        {
            add { _ticker += value; }
            remove { _ticker -= value; }
        }
        public int KeyFrameIndex { get; private set; }
    }

    partial class FrameTicker
    {
        private Action<int,int> _ticker;
        private CancellationTokenSource _cancelToken;
        private int _frameIndexCounter = 0;
        private bool _pauseFlag = false;

        private readonly static int _keyFrameOffen = 4;
        private readonly static int _frameDuration = 50;

        private void RunTick()
        {
            KeyFrameIndex = 0;
            while (true)
            {
                if(_pauseFlag)
                {
                    System.Threading.Thread.Sleep(_frameDuration);
                    continue;
                }
                UnityEngine.Debug.Log("111");
                if (_frameIndexCounter % _keyFrameOffen == 0)
                {
                    KeyFrameIndex = _frameIndexCounter / _keyFrameOffen;
                }
                _ticker?.Invoke(KeyFrameIndex, _frameIndexCounter);
                _frameIndexCounter++;
                System.Threading.Thread.Sleep(_frameDuration);
            }
        }
    }

    partial class FrameTicker
    {
        public static void Run(FrameTicker ticker)
        {
            ticker._cancelToken = new CancellationTokenSource();
            Task.Factory.StartNew(ticker.RunTick, ticker._cancelToken.Token);
        }
        public static bool IsRunning(FrameTicker ticker)
        {
            return ticker._cancelToken != null && !ticker._pauseFlag;
        }
        public static void Stop(FrameTicker ticker)
        {
            ticker._pauseFlag = true;
            if (ticker._cancelToken != null)
            {
                ticker._cancelToken.Cancel();
                ticker._cancelToken = null;
            }
        }
        public static void Pause(FrameTicker ticker)
        {
            ticker._pauseFlag = true;
        }
        public static void Resume(FrameTicker ticker)
        {
            ticker._pauseFlag = false;
        }
        public static bool IsKeyFrameTurn(int frameIndex)
        {
            return frameIndex % _keyFrameOffen == 0;
        }
        public static int FrameIndex(int keyFrameIndex,uint offset)
        {
            return keyFrameIndex * _keyFrameOffen + (int)(offset % _keyFrameOffen);
        }
    }
}
